#include <stdio.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <errno.h>
#include <unistd.h>

#define MAXLINE 10

int main(int argc, char *argv[])
{
    int efd, i;
    int pfd[2];
    pid_t pid;
    char buf[MAXLINE], ch = 'a';

    pipe(pfd);
    pid = fork();

    if (pid == 0) {             //子 写
        close(pfd[0]);//关闭读端
        while (1) {
            //aaaa\n
            for (i = 0; i < MAXLINE/2; i++)
                buf[i] = ch;
            buf[i-1] = '\n';
            ch++;
            //bbbb\n
            for (; i < MAXLINE; i++)
                buf[i] = ch;
            buf[i-1] = '\n';
            ch++;
            //buf[]:aaaa\nbbbb\n
            write(pfd[1], buf, sizeof(buf));
            sleep(5);
        }
        close(pfd[1]);//用完后关闭

    } else if (pid > 0) {       //父 读
        struct epoll_event event;
        struct epoll_event resevent[10];        //epoll_wait就绪返回event
        int res, len;

        close(pfd[1]);//关闭写端
        efd = epoll_create(10);//创建红黑树

        //event.events = EPOLLIN | EPOLLET;          // ET 边沿触发:在epoll_wait()等待,有数据突然到来时才继续
        event.events = EPOLLIN;                 // LT 水平触发 (默认)：在epoll_wait()阻塞，如果缓冲区有东西就继续
        event.data.fd = pfd[0];//指定监听的文件（大概是？）
        epoll_ctl(efd, EPOLL_CTL_ADD, pfd[0], &event);//挂上红黑树

        while (1) {
            //res 返回事件个数
            //efd epoll_create()函数返回的红黑树根节点
            //resevent epoll把发生的事件的集合从内核复制到 events数组中
            //10 本次可以返回的最大事件数目
            //-1 表示在没有检测到事件发生时最多等待的时间，超时时间(>=0)，单位是毫秒ms，-1表示阻塞，0表示不阻塞
            res = epoll_wait(efd, resevent, 10, -1);
            printf("事件个数：res %d\n", res);
            if (resevent[0].data.fd == pfd[0]) {
                len = read(pfd[0], buf, MAXLINE/2);//读一半
                write(STDOUT_FILENO, buf, len);
            }
        }

        close(pfd[0]);//用完后关闭
        close(efd);//用完后关闭

    } else {
        perror("fork");
        exit(-1);
    }

    return 0;
}

